/*
 * Copyright 2015 Ming Xia
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.healthcloud.service.impl;

import java.util.Date;
import java.util.List;

import com.healthcloud.dao.SysUserDao;
import com.healthcloud.entity.SysRoleEntity;
import com.healthcloud.entity.SysUserEntity;
import com.healthcloud.service.SysRoleService;
import org.apache.shiro.authc.credential.PasswordService;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.healthcloud.constants.UserConsts;
import com.healthcloud.entity.Condition;
import com.healthcloud.exception.BusinessException;
import com.healthcloud.service.MobileCodeService;
import com.healthcloud.service.UserService;
import com.healthcloud.utils.MobileCodeUtils;
import com.healthcloud.utils.PageParam;
import com.healthcloud.utils.Pagine;
import com.healthcloud.utils.UserErrorCode;
import com.healthcloud.utils.UserUtil;

/**
 * @author Sephy
 * @since: 2015-05-11
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {

	@Autowired
	private SysUserDao userMapper;

	@Autowired
	private PasswordService passwordService;

	@Autowired
	private MobileCodeService mobileCodeService;

	@Autowired
	private SysRoleService sysRoleService;

	@Override
	public SysUserEntity get(Long id) {
		return userMapper.queryObject(id);
	}

	@Override
	public boolean isMobileExists(String mobile) {
		return this.findByMobile(mobile) != null;
	}

	@Override
	public boolean isUsernameExists(String username) {
		return this.findByUsername(username) != null;
	}

	@Override
	public SysUserEntity findByEmail(String email) {
		return userMapper.queryByEmail(email);
	}

	@Override
	public SysUserEntity findByMobile(String mobile) {
		return userMapper.queryByMobil(mobile);
	}

	@Override
	public SysUserEntity findByUsername(String username) {
		return userMapper.queryByUserName(username);
	}

	@Override
	@Transactional
	public SysUserEntity register(String mobile, String username, String password, Integer userKind) {
		Date now = new Date();
		SysUserEntity user = new SysUserEntity();
		user.setMobile(mobile);
		user.setUsername(username);
		user.setCreateTime(now);
		user.setUpdateTime(now);
		user.setUserKind(userKind == null ? UserConsts.KIND_NORMAL : userKind.toString());
		// 密码处理
		setUserPassword(user, password);
//		user.setPassword(UserUtil.encryptPassword(user.getPassword()));
		user.setStatus(UserConsts.STATE_NORMAL);
		userMapper.save(user);

		return user;
	}

	@Override
	@Transactional
	public SysUserEntity register(SysUserEntity user) {
		if("".equals(user.getUsername()))user.setUsername(null);
		if("".equals(user.getEmail()))user.setEmail(null);
		if("".equals(user.getUserImage()))user.setUserImage(null);
		Date now = new Date();
		user.setCreateTime(now);
		user.setUpdateTime(now);
		user.setStatus(UserConsts.STATE_NORMAL);
		// 密码处理
		user.setPassword(UserUtil.encryptPassword(user.getPassword()));
		userMapper.save(user);
		return user;
	}

	@Override
	@Transactional
	public SysUserEntity register(String mobile, String username, String password, Integer userKind, String code) throws Exception {
		SysUserEntity user = register(mobile, username, password, userKind);
        if (mobile != null) { // 验证手机短信
            mobileCodeService.validate(mobile, code, MobileCodeUtils.REGISTER);
        }
		return user;
	}

	@Override
	@Transactional
	public void changePassword(Long userId, String oldPassword, String newPassword) throws Exception {
		SysUserEntity user = this.get(userId);
		doValidatePassword(user, oldPassword); // 验证原密码
		setUserPassword(user, newPassword);
		user.setUpdateTime(new Date());
		userMapper.update(user);
	}

	@Override
	@Transactional
	public Boolean changePasswordByMobile(String mobile, String oldPassword, String newPassword) {
		SysUserEntity user = this.findByMobile(mobile);
		if(user.getPassword().equals(oldPassword)){
			setUserPassword(user, newPassword);
			user.setUpdateTime(new Date());
			userMapper.update(user);
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public Boolean changePasswordByUsername(String username, String oldPassword, String newPassword) {
		SysUserEntity user = this.findByUsername(username);
		if(user.getPassword().equals(oldPassword)){
			setUserPassword(user, newPassword);
			user.setUpdateTime(new Date());
			userMapper.update(user);
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public Boolean changePasswordByEmail(String email, String oldPassword, String newPassword) {
		SysUserEntity user = this.findByEmail(email);
		if(user.getPassword().equals(oldPassword)){
			setUserPassword(user, newPassword);
			user.setUpdateTime(new Date());
			userMapper.update(user);
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public void resetPassword(Long userId, String newPassword) {
		SysUserEntity user = this.get(userId);
		if (user != null) {
			setUserPassword(user, newPassword);
			user.setUpdateTime(new Date());
			userMapper.update(user);
		}
	}

	@Override
	public SysUserEntity resetPasswordByMobile(String mobile, String newPassword, String code) throws Exception{
		SysUserEntity user = this.findByMobile(mobile);
		if (mobile != null) { // 验证手机短信
			mobileCodeService.validate(mobile, code, MobileCodeUtils.RESET);
		}
		if (user != null) {
			setUserPassword(user, newPassword);
			user.setUpdateTime(new Date());
			userMapper.update(user);
		}
		return user;
	}

	@Override
	@Transactional
	public void activateUser(Long userId) {
		SysUserEntity user = this.get(userId);
		if (user != null) {
			user.setStatus(UserConsts.STATE_NORMAL);
			user.setUpdateTime(new Date());
			userMapper.update(user);
		}
	}

	@Override
	public void lockUser(Long userId) {
		SysUserEntity user = this.get(userId);
		if (user != null) {
			user.setStatus(UserConsts.STATE_LOCKED);
			user.setUpdateTime(new Date());
			userMapper.update(user);
		}
	}

//	@Override
//	public Page<SysUserEntity> searchUsers(List<Condition<Object>> conditions, Pageable pageable) {
//		Pagine<SysUserEntity> page = new Pagine<>(pageable);
//		userMapper.criteriaSearch(conditions, page);
//		return page;
//	}

	@Override
	public boolean checkPassword(Long userId, String password) {
		SysUserEntity user = this.get(userId);
		if (user == null) {
			return false;
		}else{
			if(password.equals(user.getPassword())||password==user.getPassword()){
				return true;
			}else{
				return false;
			}
		}
		//return passwordService.passwordsMatch(password, user.getPassword());
	}

	public void validatePassword(Long userId, String password) {
		SysUserEntity user = this.get(userId);
		doValidatePassword(user, password);
	}

	@Override
	public void validateIdentity(String identity) {
		if (isMobileExists(identity)) {
			throw new BusinessException(UserErrorCode.MOBILE_EXISTS, "手机号码已使用");
		}
		if (isUsernameExists(identity)) {
			throw new BusinessException(UserErrorCode.USERNAME_EXISTS, "用户名已存在");
		}
	}

	@Override
	public void checkMobile(String mobile) {
		if (isMobileExists(mobile)) {
			throw new BusinessException(UserErrorCode.MOBILE_EXISTS);
		}
	}

	@Override
	public List<SysUserEntity> findByEntityAll(SysUserEntity entity) {
		return userMapper.queryListById(entity.getId());
	}

	@Override
	public List<SysUserEntity> search(SysUserEntity entity, PageParam pageParam) {
		return userMapper.search(entity,pageParam);
	}

	@Override
	public int count(SysUserEntity entity) {
		return userMapper.queryTotal(entity);
	}

	@Override
	public int save(SysUserEntity entity) {
		return userMapper.save(entity);
	}

	@Override
	public int update(SysUserEntity entity) {
		if("".equals(entity.getUsername()))entity.setUsername(null);
		if("".equals(entity.getEmail()))entity.setEmail(null);
		if("".equals(entity.getUserImage()))entity.setUserImage(null);

		SysUserEntity user = this.get(entity.getId());
		user.setUpdateTime(new Date());
		user.setUsername(entity.getUsername());//登录帐号
		user.setMobile(entity.getMobile());//手机号
		user.setUserImage(entity.getUserImage());//用户头像
		user.setRealName(entity.getRealName());//真实姓名
		user.setEmail(entity.getEmail());//邮箱
		user.setUserKind(entity.getUserKind());//用户类型
		return userMapper.update(user);
	}

	@Override
	public int delete(Long id) {
		return userMapper.delete(id);
	}

	@Override
	@Transactional
	public int deletes(Long[] ids) {
		int j = 0;
		for (int i = 0; i < ids.length; i++) {
			j = delete(ids[i]);
		}
		return j;
	}

	@Override
	public int logicalDelete(Long id) {
		return userMapper.logicalDelete(id);
	}

	@Override
	@Transactional
	public int logicalDeletes(Long[] ids) {
		int j = 0;
		for (int i = 0; i < ids.length; i++) {
			j = logicalDelete(ids[i]);
		}
		return j;
	}

	private void doValidatePassword(SysUserEntity user, String password) {
		if (user == null) {
			throw new BusinessException(UserErrorCode.USER_NOT_EXISTS, "用户不存在");
		}
		if (!passwordService.passwordsMatch(password, user.getPassword())) {
			throw new BusinessException(UserErrorCode.PASSWORD_NOT_MATCH, "密码错误");
		}
	}

	/**
	 * 生成密码盐值并加密用户明文密码
	 * @param user 用户对象
	 * @param password 明文密码
	 */
	private void setUserPassword(SysUserEntity user, String password) {
		//String encryptedPassword = passwordService.encryptPassword(password);
		user.setPassword(password);
	}
}
